package hongcheng.code_generator;

import java.util.Map;

import hongcheng.code_generator.config.AbstractXMLConfigReader;
import hongcheng.code_generator.config.DefaultXMLConfigReader;
import hongcheng.code_generator.data.AbstractDataReorganize;
import hongcheng.code_generator.data.DefaultDataReorganize;
import hongcheng.code_generator.database.AbstractDBMetadataReader;
import hongcheng.code_generator.database.DBMetadataReaderFactory;
import hongcheng.code_generator.entity.config.CodeGeneratorConfig;
import hongcheng.code_generator.entity.config.OutputConfig;
import hongcheng.code_generator.entity.db.TableMetadata;
import hongcheng.code_generator.templet.AbstractTempletManager;
import hongcheng.code_generator.templet.ITemplet;
import hongcheng.code_generator.templet.freemarker.FreemarkerManager;

/**
 * 	代码生成器
 * */
public class CodeGenerator {
	/**
	 * 	配置文件读取类
	 * */
	private AbstractXMLConfigReader xmlConfigReader;
	/**
	 * 	数据库元数据读取类
	 * */
	private AbstractDBMetadataReader dbMetadataReader;
	/**
	 * 	模板管理类
	 * */
	private AbstractTempletManager templetManager;
	/**
	 * 	数据重组类
	 * */
	private AbstractDataReorganize dataReorganize;
	
	
	private CodeGenerator() {}
	
	/**
	 * 	构建默认的代码生成器类
	 * 	@param xmlConfigFilePath 配置文件地址，绝对路径
	 * */
	public static CodeGenerator buildDefault(String xmlConfigFilePath) {
		CodeGenerator generator = new CodeGenerator();
		// 获取配置文件读取类
		generator.xmlConfigReader = new DefaultXMLConfigReader(xmlConfigFilePath);
		// 获取配置
		CodeGeneratorConfig codeGeneratorConfig = generator.xmlConfigReader.getCodeGeneratorConfig();
		// 获取MySQL数据库元数据读取类
		generator.dbMetadataReader = DBMetadataReaderFactory.getDBMetadataReader(codeGeneratorConfig);
		
		// 获取FreemarkerManager模板管理类
		generator.templetManager = new FreemarkerManager(codeGeneratorConfig);
		// 获取数据重组类
		generator.dataReorganize = new DefaultDataReorganize();
		return generator;
	}
	/**
	 * 	构建自定义的代码生成器
	 * 	@param xmlConfigReader  配置文件读取类
	 *  @param dbMetadataReader  数据库元数据读取类
	 *  @param templetManager  模板管理类
	 *  @param dataReorganize  数据重组类
	 *  @return CodeGenerator 代码生成器类实例
	 * */
	public static CodeGenerator build(AbstractXMLConfigReader xmlConfigReader,AbstractDBMetadataReader dbMetadataReader
			,AbstractTempletManager templetManager,AbstractDataReorganize dataReorganize) {
		CodeGenerator generator = new CodeGenerator();
		generator.xmlConfigReader = xmlConfigReader;
		generator.dbMetadataReader = dbMetadataReader;
		generator.templetManager = templetManager;
		generator.dataReorganize = dataReorganize;
		return generator;
	}
	
	
	
	
	/**
	 * 	生成代码
	 * @throws Exception 
	 * */
	public void codeGenerate( ) {
		System.out.println("正在准备生成代码   =========>>>>>>>>>>>");
		System.out.println("");
		//1、读取代码生成配置XML文件
		CodeGeneratorConfig codeGeneratorConfig = this.xmlConfigReader.getCodeGeneratorConfig();
		//2、读取数据库元数据
		TableMetadata dbMetadata = this.dbMetadataReader.getDBMetadata();
		//3、读取模板文件
		ITemplet controllerTemplet = this.templetManager.getControllerTemplet();
		ITemplet serviceTemplet = this.templetManager.getServiceTemplet();
		ITemplet serviceImplTemplet = this.templetManager.getServiceImplTemplet();
		ITemplet daoTemplet = this.templetManager.getDaoTemplet();
		ITemplet entityTemplet = this.templetManager.getEntityTemplet();
		ITemplet queryvOTemplet = this.templetManager.getQueryvOTemplet();
		ITemplet xmlTemplet = this.templetManager.getXMLTemplet();
		//4、模板与数据整合,同时保存文件
		Map<?, ?> dataMap = this.dataReorganize.getDataMap(codeGeneratorConfig,dbMetadata);
		//5、生成代码并保存
		OutputConfig outputConfig = codeGeneratorConfig.getOutputConfig();
		controllerTemplet.process(dataMap, outputConfig.getControllerOutputPath());
		System.out.println(String.format("%-25s===>   %s" ,"controller文件代码生成成功", outputConfig.getControllerOutputPath()));
		
		serviceTemplet.process(dataMap, outputConfig.getServiceOutputPath());
		System.out.println(String.format("%-25s===>   %s" ,"service文件代码生成成功" , outputConfig.getServiceOutputPath()));
		
		serviceImplTemplet.process(dataMap, outputConfig.getServiceImplOutputPath());
		System.out.println(String.format("%-25s===>   %s" ,"serviceImpl文件代码生成成功" , outputConfig.getServiceImplOutputPath()));
		
		daoTemplet.process(dataMap, outputConfig.getDaoOutputPath());
		System.out.println(String.format("%-25s===>   %s" ,"dao文件代码生成成功" , outputConfig.getDaoOutputPath()));
		
		entityTemplet.process(dataMap, outputConfig.getEntityOutputPath());
		System.out.println(String.format("%-25s===>   %s" ,"entity文件代码生成成功" , outputConfig.getEntityOutputPath()));
		
		queryvOTemplet.process(dataMap, outputConfig.getQueryVOOutputPath());
		System.out.println(String.format("%-25s===>   %s" ,"queryVO文件代码生成成功" , outputConfig.getQueryVOOutputPath()));
		
		xmlTemplet.process(dataMap, outputConfig.getMapperXMLOutputPath());
		System.out.println(String.format("%-25s===>   %s" ,"xml文件代码生成成功" , outputConfig.getMapperXMLOutputPath()));
		
		System.out.println("");
		System.out.println("<<<<<<<<<<<===========   全部代码生成成功");
	}


	public AbstractXMLConfigReader getXmlConfigReader() {
		return xmlConfigReader;
	}


	public void setXmlConfigReader(AbstractXMLConfigReader xmlConfigReader) {
		this.xmlConfigReader = xmlConfigReader;
	}

	public AbstractDBMetadataReader getDbMetadataReader() {
		return dbMetadataReader;
	}

	public void setDbMetadataReader(AbstractDBMetadataReader dbMetadataReader) {
		this.dbMetadataReader = dbMetadataReader;
	}

	public AbstractTempletManager getTempletManager() {
		return templetManager;
	}

	public void setTempletManager(AbstractTempletManager templetManager) {
		this.templetManager = templetManager;
	}

	public AbstractDataReorganize getDataReorganize() {
		return dataReorganize;
	}

	public void setDataReorganize(AbstractDataReorganize dataReorganize) {
		this.dataReorganize = dataReorganize;
	}
	
	
	
	
	
}
